#include <string.h>
#include <stdio.h>
#include "./crc/crc32.h"
#include "./image_struct/image_struct.h"

#define APP_2_0_PATH  "../bin/lock-app-2_0.bin"
#define APP_3_0_PATH  "../bin/lock-app-3_0.bin"
#define APP_PATH      "../bin/lock-app.bin"

#define APP_2_0_VERSION  0x01020304
#define APP_3_0_VERSION  0x01020304

static unsigned long file_size(char* filename);
static void mergefile(FILE *fp1,FILE *fp2,char *name);

int main(int argc, char *argv[])
{
	printf("创建工厂烧录固件...!\r\n");

	FILE *fp_2_0 = NULL;
	FILE *fp_3_0 = NULL;
	FILE * factory_firmware_file = NULL;

	unsigned long code_2_0_len = 0;
	unsigned long crc32_2_0 = 0;
	unsigned long code_3_0_len = 0;
	unsigned long crc32_3_0 = 0;


	fp_2_0 = fopen(APP_2_0_PATH,"rb");
    if(fp_2_0 == NULL)
	{
	    printf("fail to open the fp_2_0! \n");
		return -1;
	}
	fp_3_0 = fopen(APP_3_0_PATH,"rb");
    if(fp_3_0 == NULL)
	{
	    printf("fail to open the fp_3_0! \n");
		return -1;
	}

    code_2_0_len = file_size(APP_2_0_PATH);
	Crc32_ComputeFile(fp_2_0, &crc32_2_0);

	code_3_0_len = file_size(APP_3_0_PATH);
	Crc32_ComputeFile(fp_3_0, &crc32_3_0);

	printf("Crc32_ComputeFile 2.0 len 0x%x crc32 0x%x 3.0 len 0x%x crc32 0x%x \r\n",code_2_0_len,crc32_2_0,code_3_0_len,crc32_3_0) ;

	app_header_t app_header_2_0;
	app_header_t app_header_3_0;

    app_header_2_0.magic = APP_HEADER_MAGIC;
	app_header_2_0.app_type = APP_TYPE_1_MAGIC;
    app_header_2_0.version = APP_2_0_VERSION;
	app_header_2_0.code_len = code_2_0_len;
	app_header_2_0.code_crc = crc32_2_0;

    app_header_3_0.magic = APP_HEADER_MAGIC;
	app_header_3_0.app_type = APP_TYPE_1_MAGIC;
    app_header_3_0.version = APP_2_0_VERSION;
	app_header_3_0.code_len = code_3_0_len;
	app_header_3_0.code_crc = crc32_3_0;

    uint32_t header_2_0_crc = 0;
    uint32_t header_2_0_len =  APP_HEADER_SIZE - APP_HEADER_CRC_DATA_LEN;
	Crc32_ComputeBufDate((const void *)&app_header_2_0.magic,header_2_0_len ,(unsigned long *)&header_2_0_crc);
	app_header_2_0.header_len = header_2_0_len;
	app_header_2_0.header_crc = header_2_0_crc;


    uint32_t header_3_0_crc = 0;
    uint32_t header_3_0_len =  APP_HEADER_SIZE - APP_HEADER_CRC_DATA_LEN;
	Crc32_ComputeBufDate((const void *)&app_header_3_0.magic,header_3_0_len ,(unsigned long *)&header_3_0_crc);
    app_header_3_0.header_len = header_3_0_len;
	app_header_3_0.header_crc = header_3_0_crc;


	fp_2_0 = fopen(APP_2_0_PATH,"rb");
    if(fp_2_0 == NULL)
	{
	    printf("fail to open the fp_2_0! \n");
		return -1;
	}
	fp_3_0 = fopen(APP_3_0_PATH,"rb");
    if(fp_3_0 == NULL)
	{
	    printf("fail to open the fp_3_0! \n");
		return -1;
	}

	factory_firmware_file = fopen(APP_PATH, "wb");
    if(factory_firmware_file == NULL)
	{
	    printf("fail to open the factory_firmware_file! \n");
		return -1;
	}

	fwrite((const void* )&app_header_2_0, APP_HEADER_SIZE, 1, factory_firmware_file);


    fseek(factory_firmware_file, 0x100, SEEK_SET);
    
	unsigned char read_data[1];
    while(fread(read_data, 1, 1, fp_2_0) == 1)
    {
        fwrite(read_data, 1, 1, factory_firmware_file);
    }


    fseek(factory_firmware_file, WHOLE_APP_MAX_LIMIT_SIZE, SEEK_SET);

	fwrite((const void* )&app_header_3_0, APP_HEADER_SIZE, 1, factory_firmware_file);

    fseek(factory_firmware_file, 0x100 + WHOLE_APP_MAX_LIMIT_SIZE, SEEK_SET);
    
    while(fread(read_data, 1, 1, fp_3_0) == 1)
    {
        fwrite(read_data, 1, 1, factory_firmware_file);
    }

	if (fp_2_0)
		fclose(fp_2_0);

	if (fp_3_0)
		fclose(fp_3_0);

	if (factory_firmware_file)
		fclose(factory_firmware_file);

    printf("创建工厂烧录固件成功!\r\n");
    return (0);
}


static unsigned long file_size(char* filename)
{
    FILE *fp=fopen(filename,"r");
    if(!fp) return -1;
    fseek(fp,0L,SEEK_END);
    int size=ftell(fp);
    fclose(fp);

    return size;
}
